package com.example.demo.service.imply;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.exception.MyUncheckedException;
import com.example.demo.mapper.QuestionFileMapper;
import com.example.demo.mapper.SubjectFileMapper;
import com.example.demo.mapper.SubjectMapper;
import com.example.demo.pojo.tree.TreeSubjectFile;
import com.example.demo.pojo.dto.SubjectFileDTO;
import com.example.demo.pojo.entity.QuestionFile;
import com.example.demo.pojo.entity.Subject;
import com.example.demo.pojo.entity.SubjectFile;
import com.example.demo.pojo.query.FileQuery;
import com.example.demo.pojo.vo.SubjectFileShowVO;
import com.example.demo.service.ISubjectFileService;
import com.example.demo.utils.UnitTreeSolveData;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 21172
 */
@Service
@RequiredArgsConstructor
public class ISubjectFileServiceImply extends ServiceImpl<SubjectFileMapper, SubjectFile> implements ISubjectFileService {
    private final SubjectFileMapper subjectFileMapper;
    private final SubjectMapper subjectMapper;
    private final QuestionFileMapper questionFileMapper;

    //辅助函数--构建所需要的树枝
    TreeSubjectFile initTreeSubjectFile(SubjectFile nodeSubjectFile, List<Integer> needIdList) {
        if (nodeSubjectFile == null) {
            return null;
        }
        TreeSubjectFile tempTreeSubjectFile = new TreeSubjectFile();
        tempTreeSubjectFile.initSubjectFile(nodeSubjectFile);
        //查找这个节点下的所有子节点
        String childNodeId = nodeSubjectFile.getNodeId();
        QueryWrapper<SubjectFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight("node_id", childNodeId);
        queryWrapper.eq("level", nodeSubjectFile.getLevel() + 1);
        List<SubjectFile> childrenList = subjectFileMapper.selectList(queryWrapper);
        for (int i = 0; i < childrenList.size(); i++) {
            if (needIdList.contains(childrenList.get(i).getId())) {
                TreeSubjectFile tempTree = initTreeSubjectFile(childrenList.get(i), needIdList);
                if (tempTree != null) {
                    tempTreeSubjectFile.addChild(tempTree);
                }
            }
        }
        return tempTreeSubjectFile;
    }
    //辅助函数--递归构建树
    List<SubjectFileShowVO> solveFileSubjectShowVO(List<TreeSubjectFile> children) {
        if (children == null) {
            return null;
        }
        List<SubjectFileShowVO> result = new ArrayList<>();
        for (int i = 0; i < children.size(); i++) {
            TreeSubjectFile treeSubjectFile = children.get(i);
            SubjectFile subjectFile = treeSubjectFile.getSubjectFile();
            SubjectFileShowVO subjectFileShowVO = new SubjectFileShowVO();
            subjectFileShowVO.initSubjectFile(subjectFile);
            List<SubjectFileShowVO> solveResult = solveFileSubjectShowVO(treeSubjectFile.getChildren());
            subjectFileShowVO.setSubjectFileList(solveResult);
            result.add(subjectFileShowVO);
        }
        return result;
    }
    //辅助函数--处理移动文件
    void solveShiftSubjectFile(SubjectFile solveSubjectFile,SubjectFile goalSubjectFile,int presentLevel){
        //获取操作所需要的基本信息;
        String parentNodeId=goalSubjectFile.getNodeId();
        int solveSubjectFileId=solveSubjectFile.getId();
        String solveNdeId=solveSubjectFile.getNodeId();
        UnitTreeSolveData unitTreeSolve=new UnitTreeSolveData();
        //查找出这个文件下的所有题目
        QueryWrapper<QuestionFile>queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("file_id",solveSubjectFileId);
        List<QuestionFile>questionFileList=questionFileMapper.selectList(queryWrapper);
        //更改当前文件夹的位值
        String contactNodeId=unitTreeSolve.spiltNodeIdForChildren(solveNdeId,presentLevel);
        System.out.println("分隔后的id"+contactNodeId);
        String newNodeId=parentNodeId+contactNodeId;
        System.out.println("newNodeId"+newNodeId);
        int newLevel=unitTreeSolve.getLevel(newNodeId);
        solveSubjectFile.setNodeId(newNodeId);
        solveSubjectFile.setLevel(newLevel);
        UpdateWrapper<SubjectFile>updateFileWrapper=new UpdateWrapper<>();
        updateFileWrapper.eq("id",solveSubjectFile.getId());
        subjectFileMapper.update(solveSubjectFile,updateFileWrapper);
        //更改文件夹下题目的位置
//        for(QuestionFile questionFileFor:questionFileList){
//            UpdateWrapper<QuestionFile>updateQuestionFileWrapper = new UpdateWrapper<>();
//            updateQuestionFileWrapper.eq("file_id",questionFileFor.getFileId());
//            questionFileFor.setFileId(goalSubjectFile.getId());
//            questionFileMapper.update(questionFileFor,updateQuestionFileWrapper);
//        }
    }
    //辅助函数--处理复制文件
    SubjectFile solveQuestionFile(int subjectFileId,SubjectFile goalSubjectFile ){
        //获取操作需要的基本数据--一个是当前处理，另一个是已经被更新过的父节点
        System.out.println("进入到处理函数");
        UnitTreeSolveData unitTreeSolve=new UnitTreeSolveData();
        SubjectFile solveSubjectFile=subjectFileMapper.selectById(subjectFileId);
        //查找这个文件下的
        QueryWrapper<QuestionFile>queryWrapperQuestion=new QueryWrapper<>();
        queryWrapperQuestion.eq("file_id",subjectFileId);
        List<QuestionFile>questionFileList=questionFileMapper.selectList(queryWrapperQuestion);
        //构建新file后执行新增的操作
        SubjectFile copySubjectFile=new SubjectFile();
        copySubjectFile.initSubjectFile(solveSubjectFile);
        subjectFileMapper.insert(copySubjectFile);
        int newId=copySubjectFile.getId();
        String newNode=goalSubjectFile.getNodeId()+ newId +"-";
        int newLevel=goalSubjectFile.getLevel()+1;
        UpdateWrapper<SubjectFile>updateWrapper=new UpdateWrapper<>();
        updateWrapper.eq("id",newId);
        copySubjectFile.setLevel(newLevel);
        copySubjectFile.setNodeId(newNode);
        subjectFileMapper.update(copySubjectFile,updateWrapper);
        //执行相关题目的复制
        int newSubjectId=copySubjectFile.getId();
        for(QuestionFile questionFile:questionFileList){
            questionFile.setFileId(newSubjectId);
            QuestionFile insert=new QuestionFile();
            insert.copyQuestionFile(questionFile);
            questionFileMapper.insert(insert);
        }
        return copySubjectFile;
    }
    //辅助函数--进行树文件的删除
    void solveDeleteSubjectFile(int subjectFileId){
        //查找这个文件夹下的所有题目表
        QueryWrapper<QuestionFile>queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("file_id",subjectFileId);
        List<QuestionFile>questionFileList=questionFileMapper.selectList(queryWrapper);
        List<Integer> idList = questionFileList.stream()
                .map(QuestionFile::getId)
                .collect(Collectors.toList());
        System.out.println(idList);
        if(!idList.isEmpty()){
            questionFileMapper.deleteBatchIds(idList);
        }
    }
    //辅助函数--构建中左右的树
    void createTreeSubjectFile(int subjectFileId,List<Integer>idList){
        idList.add(subjectFileId);
        SubjectFile subjectFile=subjectFileMapper.selectById(subjectFileId);
        String newNode=subjectFile.getNodeId();
        int level=subjectFile.getLevel();
        QueryWrapper<SubjectFile>queryWrapper=new QueryWrapper<>();
        queryWrapper.likeRight("node_id",newNode);
        queryWrapper.eq("level",level+1);
        List<SubjectFile>list=subjectFileMapper.selectList(queryWrapper);
        for(int i=0;i<list.size();i++){
            createTreeSubjectFile(list.get(i).getId(),idList);
        }
    }
    /**
     * 打包函数：根据根节点构建树然后打包成VO返回
     * @author: fjh
    **/
    List<SubjectFileShowVO> completeSubjectVOList(SubjectFile rootSubjectFile, List<Integer> needIdList) {
        List<SubjectFileShowVO> result = new ArrayList<>();
        TreeSubjectFile treeSubjectFile = initTreeSubjectFile(rootSubjectFile, needIdList);
        SubjectFileShowVO subjectFileShowVO = new SubjectFileShowVO();
        subjectFileShowVO.initSubjectFile(rootSubjectFile);
        List<SubjectFileShowVO> solveResult = solveFileSubjectShowVO(treeSubjectFile.getChildren());
        subjectFileShowVO.setSubjectFileList(solveResult);
        for (int i = 0; i < solveResult.size(); i++) {
            result.add(solveResult.get(i));
        }
        return result;
    }
    //处理函数--添加文件
    @Override
    public int addFile(SubjectFileDTO subjectFileDTO) {
        if (subjectFileDTO != null) {
            int fileId = subjectFileDTO.getFileId();
            SubjectFile psubjectFile = subjectFileMapper.selectById(fileId);
            SubjectFile csubjectFile = new SubjectFile();
            if (psubjectFile != null) {
                csubjectFile.setParentId(psubjectFile.getId());
                csubjectFile.setFileName(subjectFileDTO.getFileName());
                csubjectFile.setLevel(psubjectFile.getLevel() + 1);
                csubjectFile.setCreateUser(subjectFileDTO.getCreateUser());
                subjectFileMapper.insert(csubjectFile);
                int subjectFileId = csubjectFile.getId();
                String nodeId = psubjectFile.getNodeId();
                String newNodeId = nodeId + String.valueOf(subjectFileId) + "-";
                csubjectFile.setNodeId(newNodeId);
                UpdateWrapper<SubjectFile> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", csubjectFile.getId());
                if (subjectFileMapper.update(csubjectFile, updateWrapper) > 0) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }
        return 0;
    }
    //处理函数--初始化文件列表
    /**
     * 初始化文件列表
     * @author: fjh
     * @param: [fileQuery]
     * @return: java.util.List<com.example.demo.pojo.vo.SubjectFileShowVO>
    **/
    @Override
    public List<SubjectFileShowVO> initFile(FileQuery fileQuery) {
        int subjectId=fileQuery.getSubjectId();
        Subject subject = subjectMapper.selectById(subjectId);
        //默认查询学科根目录下的所有题目
        int fileId = subject.getLabelId();
        SubjectFile roootSubjectFile = subjectFileMapper.selectById(fileId);
        if (roootSubjectFile != null) {
            QueryWrapper<SubjectFile> queryWrapper = new QueryWrapper<>();
            queryWrapper.likeRight("node_id",fileId+"-");
            List<Integer> needIdList = subjectFileMapper.selectList(queryWrapper).stream().map(SubjectFile::getId).collect(Collectors.toList());
            List<SubjectFileShowVO>completeList=completeSubjectVOList(roootSubjectFile, needIdList);
            SubjectFileShowVO result=new SubjectFileShowVO();
            result.initSubjectFile(roootSubjectFile);
            result.setSubjectFileList(completeList);
            List<SubjectFileShowVO> listResult=new ArrayList<>();
            listResult.add(result);
            return listResult;
        }
        return null;
    }
    /**
     * 将文件夹以及文件夹下的题目转移到另外一个文件夹下
     * @author: fjh
     * @param: subjectFileId：被转移的文件夹Id
     * @param: goalSubjectFileId：目标的文件夹Id
     * @return: SubjectFile：转移后新文件夹的信息
    **/
    @Override
    public SubjectFile shiftSubjectFile(int subjectFileId, int goalSubjectFileId) {
        SubjectFile subjectFile = subjectFileMapper.selectById(subjectFileId);
        SubjectFile goalSubjectFile = subjectFileMapper.selectById(goalSubjectFileId);
        int presentLevel=subjectFile.getLevel();
        //获取相关文件
        QueryWrapper<SubjectFile>queryWrapper=new QueryWrapper<>();
        String nodeId=subjectFile.getNodeId();
        queryWrapper.likeRight("node_id",nodeId);

        List<SubjectFile>subjectFileList=subjectFileMapper.selectList(queryWrapper);
        System.out.println(subjectFileList.size());
        for(SubjectFile subjectFileFor:subjectFileList){
            solveShiftSubjectFile(subjectFileFor,goalSubjectFile,presentLevel);
        }
        return subjectFile;
    }
    /**
     * 根据id查找file
     * @author: fjh
     * @param: fileId：文件的id
    **/
    @Override
    public SubjectFile searchById(int fileId) {
        return subjectFileMapper.selectById(fileId);
    }
    @Override
    public SubjectFile updateFile(SubjectFileDTO subjectFileDTO)  {
        int subjectFileId=subjectFileDTO.getFileId();
        SubjectFile subjectFile=subjectFileMapper.selectById(subjectFileId);
        if(subjectFileDTO.getCreateUser()!=null&& !subjectFileDTO.getCreateUser().isEmpty()){
            subjectFile.setCreateUser(subjectFileDTO.getCreateUser());
        }
        if(subjectFileDTO.getFileName()!=null&&!subjectFileDTO.getFileName().isEmpty()){
            subjectFile.setFileName(subjectFileDTO.getFileName());
        }
        UpdateWrapper<SubjectFile>updateWrapper=new UpdateWrapper<>();
        updateWrapper.eq("id",subjectFileId);
        subjectFileMapper.update(subjectFile,updateWrapper);
        return subjectFile;
    }

    @Override
    public boolean deleteFile(int subjectFileId) throws MyUncheckedException {
        //进行检查--根目录无法被删除
        QueryWrapper<Subject>queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("file_id",subjectFileId);
        if(!subjectMapper.selectObjs(queryWrapper).isEmpty()){
            throw new MyUncheckedException("无法删除根目录");
        }
        //查询该文件夹下的所有子文件夹
        List<Integer>treeIdList=new ArrayList<>();
        createTreeSubjectFile(subjectFileId,treeIdList);
        for(Integer subjectFileIdFor:treeIdList){
            System.out.println("当前删除的文件夹是"+subjectFileIdFor);
            solveDeleteSubjectFile(subjectFileIdFor);
            //删除文件夹下的题目后再进行文件的删除
            subjectFileMapper.deleteById(subjectFileIdFor);
        }
        return true;
    }

    //处理函数--复制文件
    @Override
    public SubjectFile copySubjectFile(int subjectFileId,int goalSubjectFileId) {
        SubjectFile subjectFile = subjectFileMapper.selectById(subjectFileId);
        SubjectFile goalSubjectFile = subjectFileMapper.selectById(goalSubjectFileId);
        List<Integer>fileIdList=new ArrayList<>();
        //获得复制文件下所有的文件id
        createTreeSubjectFile(subjectFileId,fileIdList);
        System.out.println("树的结构id"+fileIdList);
        //进行处理
        HashMap<Integer,Integer>changeIdMap=new HashMap<>();
        HashMap<Integer,SubjectFile>changeSubjectFileMap=new HashMap<>();
        SubjectFile parentSubjectFile=goalSubjectFile;
        SubjectFile preNewSubjectFile=goalSubjectFile;
        SubjectFile preOldSubjectFile=goalSubjectFile;
        SubjectFile presentSubjectFile=new SubjectFile();
        int presentLevel;
        int preLevel=0;
        int parentLevel=0;
        int flag=1;
        /*使用的数据不能是更新以后的，因为更新后树的结构被破坏。
        level属于更新前数据，插入后的subjectFile属于更新后的数据,id属于更新前的数据先前的pre要在操作前完成更新
        处理的数据应该是新旧结合*/
        System.out.println("开始处理");
        for(int i:fileIdList){
            presentSubjectFile=subjectFileMapper.selectById(i);
            System.out.println("处理的是"+presentSubjectFile);
            presentLevel=presentSubjectFile.getLevel();
            System.out.println("当前数据 preLevel"+preLevel);
            System.out.println("当前数据 parentLevel"+parentLevel);
            if(flag==1){
                System.out.println("第一次进入");
                preLevel=presentLevel;
                parentLevel=parentSubjectFile.getLevel();
                preOldSubjectFile=presentSubjectFile;
                preNewSubjectFile=solveQuestionFile(i,parentSubjectFile);
                parentSubjectFile=presentSubjectFile;
                flag=0;
                continue;
            }
            if(preLevel<presentLevel){
                System.out.println("更高节点");
                //当前处理的节点高层的节点--说明要更换父节点
                int oldId=preOldSubjectFile.getId();
                int newId=preNewSubjectFile.getId();
                changeIdMap.put(oldId, newId);
                //保存父节点
                changeSubjectFileMap.put(newId, preNewSubjectFile);
                //变更变量
                parentSubjectFile=preNewSubjectFile;
                preLevel=presentLevel;
                preOldSubjectFile=presentSubjectFile;
                preNewSubjectFile=solveQuestionFile(i,parentSubjectFile);
                continue;
            }else if(preLevel==presentLevel){
                System.out.println("同等级节点");
                //当前处理的是与上一级相同的同级情况
                preLevel=presentLevel;
                preOldSubjectFile=presentSubjectFile;
                preNewSubjectFile=solveQuestionFile(i,parentSubjectFile);
                continue;
            }else if(presentLevel<preLevel){
                System.out.println("变层节点");
                int presentParentId=presentSubjectFile.getParentId();
                //通过当前处理文件的父类id获取更新后的id，再获取到更新后的文件，作为父节点。为了更新nodeId
                parentSubjectFile=changeSubjectFileMap.get(changeIdMap.get(presentParentId));
                System.out.println("这是寻找到的父节点"+parentSubjectFile);
                preLevel=presentLevel;
                preOldSubjectFile=presentSubjectFile;
                preNewSubjectFile=solveQuestionFile(i,parentSubjectFile);
                continue ;
            }
        }

        return subjectFile;
    }
}
